using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
/// Summary description for CardValidator
/// </summary>
public class CardValidator
{
    public CardValidator() { }

    /// <summary>
    /// Detect illegal card number
    /// </summary>
    public bool Check(string cardNo, string cardType)
    {
        byte[] digits = StringToByteArray(cardNo);
        int length = digits.Length;

        switch (cardType)
        {
            case "Master":
                if (length != 16) return false;
                if (digits[0] != 5 || digits[1] == 0 || digits[1] > 5) return false;
                break;
            case "Visa":
                if (length != 16 && length != 13) return false;
                if (digits[0] != 4) return false;
                break;
            default:
                return false;
        }

        return CheckLuhn(digits);
    }

    /// <summary>
    /// Check if the card is existent
    /// </summary>
    public bool CheckExists(string cardNo, string cardType)
    {
        byte[] encrypted = new Encryptor().SHA1Encrypt(cardNo);
        CardSystemWS.Service proxy = new CardSystemWS.Service();
        proxy.PreAuthenticate = true;
        proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
        switch (cardType)
        {
            case "Master":
                return proxy.MasterCardExists(encrypted);
            case "Visa":
                return proxy.VisaCardExists(encrypted);
            default:
                return false;
        }
    }

    /// <summary>
    /// Convert string to byte[] for Luhn checking
    /// </summary>
    private byte[] StringToByteArray(string strDigit)
    {
        int l = strDigit.Length;
        byte[] digits = new byte[l];
        for (int i = 0; i < l; i++)
        {
            digits[i] = byte.Parse(strDigit[i].ToString());
        }
        return digits;
    }

    /// <summary>
    /// Luhn checker
    /// </summary>
    private bool CheckLuhn(byte[] digits)
    {
        int sum = 0;
        bool alt = false;
        for (int i = digits.Length - 1; i >= 0; i--)
        {
            if (alt)
            {
                digits[i] *= 2;
                if (digits[i] > 9) digits[i] -= 9;
            }
            sum += digits[i];
            alt = !alt;
        }
        return sum % 10 == 0;
    }

    /// <summary>
    /// Check whether the card is expired
    /// </summary>
    public bool CheckExpired(byte[] encryptedCardNo, string cardType)
    {
        CardSystemWS.Service proxy = new CardSystemWS.Service();
        proxy.PreAuthenticate = true;
        proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
        switch (cardType)
        {
            case "Master":
                return proxy.MasterCardExpired(encryptedCardNo);
            case "Visa":
                return proxy.VisaCardExpired(encryptedCardNo);
            default:
                return false;
        }
    }
}
